package be.phl.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import be.phl.obstacleapp.MainData;
import be.phl.webservice.Building;
import be.phl.webservice.BuildingDetail;
import be.phl.webservice.Patient;
import be.phl.webservice.PatientBundle;
import be.phl.webservice.PatientDetail;
import be.phl.webservice.PatientMovementRestriction;
import be.phl.webservice.PatientUsedAid;
import be.phl.webservice.ScreeningBundle;
import be.phl.webservice.ScreeningBundle.ScreeningItemBundle;
import be.phl.webservice.ScreeningBundle.ScreeningRoomBundle;
import be.phl.webservice.ScreeningItem;
import be.phl.webservice.ScreeningProblem;
import be.phl.webservice.ScreeningRoom;

public class DBAdapterUpload extends DBAdapter {

	public DBAdapterUpload(Context ctx) {
		super(ctx);
		// TODO Auto-generated constructor stub
	}

	public int getAmountCities() {
		Cursor c = db.query("City", new String[] { KEY_ROWID }, null, null,
				null, null, null);
		return c.getCount();
	}

	/**
	 * get all the screenings to be uploaded
	 * 
	 * a map is used to link the tablet id to a bundle
	 * @return
	 */
	public Map<Integer, ScreeningBundle> getScreeningBundle() {

		int screeningId;
		Map<Integer, ScreeningBundle> sbList = new HashMap<Integer, ScreeningBundle>();
		Cursor cScreening = db
				.rawQuery(
						"SELECT Screening.*, ScreeningUser._id FROM ScreeningUser, Screening "
								+ "WHERE ScreeningUser.UserId=? AND Screening._id=ScreeningUser.ScreeningId AND Screening.Finished='T'",
						new String[] { MainData.getLoggedUser().getId()
								.toString() });

		if (cScreening.getCount() == 0) {
			return null;
		}
		while (cScreening.moveToNext()) {
			screeningId = cScreening.getInt(0);
			ScreeningBundle sb = new ScreeningBundle();
			sb.setScreeningId(cScreening.getInt(1));
			sb.setPatientId(cScreening.getInt(2));
			sb.setBuildingId(cScreening.getInt(3));
			sb.setDate(cScreening.getString(4));
			sb.setComment(cScreening.getString(5));

			Cursor cRoom = db.query("ScreeningRoom", new String[] { KEY_ROWID,
					"RoomTypeId", "Comment", "Name", "ReferenceNumber",
					"FloorNumber" }, "ScreeningId=?",
					new String[] { cScreening.getString(0) }, null, null, null);

			List<ScreeningRoomBundle> srbList = new ArrayList<ScreeningRoomBundle>();
			while (cRoom.moveToNext()) {

				ScreeningRoom sr = new ScreeningRoom();
				sr.setRoomType(cRoom.getInt(1));
				sr.setComment(cRoom.getString(2));
				sr.setName(cRoom.getString(3));
				sr.setReferenceNumber(cRoom.getInt(4));
				sr.setFloorNumber(cRoom.getInt(5));

				Cursor cItem = db.query("ScreeningItem", new String[] {
						KEY_ROWID, "RoomItemId", "Comment" },
						"ScreeningRoomId=?",
						new String[] { cRoom.getString(0) }, null, null, null);

				List<ScreeningItemBundle> sibList = new ArrayList<ScreeningItemBundle>();
				while (cItem.moveToNext()) {
					ScreeningItemBundle sib = new ScreeningItemBundle();
					ScreeningItem si = new ScreeningItem();
					si.setRoomItem(cItem.getInt(1));
					si.setComment(cItem.getString(2));
					si.setTabletId(cItem.getInt(0));

					Cursor cProblem = db
							.query("ScreeningProblem", new String[] {
									KEY_ROWID, "ItemProblemId", "Value" },
									"ScreeningItemId=?",
									new String[] { cItem.getString(0) }, null,
									null, null);
					if (cProblem.getCount() > 0) {
						List<ScreeningProblem> spList = new ArrayList<ScreeningProblem>();
						while (cProblem.moveToNext()) {

							ScreeningProblem sp = new ScreeningProblem();
							sp.setItemProblem(cProblem.getInt(1));
							sp.setValue(cProblem.getString(2));
							spList.add(sp);
						}
						sib.setScreeningProblem(spList);
					}
					sib.setScreeningItem(si);

					sibList.add(sib);
				}
				ScreeningRoomBundle srb = new ScreeningRoomBundle();
				srb.setScreeningItemBundle(sibList);
				srb.setScreeningRoom(sr);
				srbList.add(srb);
			}
			sb.setScreeningRoomBundle(srbList);

			// patients data
			PatientBundle pb = new PatientBundle();

			Cursor cPatient = db.query("Patient", new String[] { KEY_ROWID,
					"FirstName", "LastName", "Email", "TelNumber", "Gender",
					"DayOfBirth", "Weight", "Length", "BuildingId",
					"MaritalStatus", "ContactFirstName", "ContactLastName",
					"ContactRelation", "ContactTelNumber", "ContactEmail" },
					"_id=?",
					new String[] { Integer.toString(cScreening.getInt(2)) },
					null, null, null);
			cPatient.moveToFirst();
			Patient p = new Patient();
			p.setId(cPatient.getInt(0));
			p.setFirstName(cPatient.getString(1));
			p.setLastName(cPatient.getString(2));
			p.setEmail(cPatient.getString(3));
			p.setTelNumber(cPatient.getString(4));
			p.setGender(cPatient.getString(5));
			p.setDayOfBirthString(cPatient.getString(6));
			p.setWeight(cPatient.getInt(7));
			p.setLength(cPatient.getInt(8));
			p.setMaritalStatus(cPatient.getInt(10));
			p.setContactFirstName(cPatient.getString(11));
			p.setContactLastName(cPatient.getString(12));
			p.setContactRelation(cPatient.getString(13));
			p.setContactTelNumber(cPatient.getString(14));
			p.setContactEmail(cPatient.getString(15));

			Cursor cBuilding = db.query("Building", new String[] { KEY_ROWID,
					"Street", "Number", "CityId", "YearOfConstruction",
					"BuildingTypeId" }, "_id=?",
					new String[] { Integer.toString(cPatient.getInt(9)) },
					null, null, null);
			cBuilding.moveToFirst();
			Building b = new Building();
			b.setId(cBuilding.getInt(0));
			b.setStreet(cBuilding.getString(1));
			b.setNumber(cBuilding.getString(2));
			b.setCity(3);
			b.setYearOfConstructionString(cBuilding.getString(4));
			b.setBuildingType(cBuilding.getInt(5));

			p.setBuilding(b);
			pb.setPatient(p);

			Cursor cDetail = db.query("PatientDetail", new String[] {
					"CentralId", "patientId", "patientSpecId", "Value" },
					"patientId=?",
					new String[] { Integer.toString(cPatient.getInt(0)) },
					null, null, null);
			List<PatientDetail> pdList = new ArrayList<PatientDetail>();
			while (cDetail.moveToNext()) {
				PatientDetail pd = new PatientDetail();
				pd.setId(cDetail.getInt(0));
				pd.setPatient(cDetail.getInt(1));
				pd.setPatientSpec(cDetail.getInt(2));
				pd.setValue(cDetail.getString(3));
				pdList.add(pd);
			}
			pb.setPatientDetail(pdList);
			Cursor cMov = db.query("PatientMovementRestriction", new String[] {
					"CentralId", "patientId", "MovementRestrictionId",
					"PatientUsedAidId", "Value" }, "patientId=?",
					new String[] { Integer.toString(cPatient.getInt(0)) },
					null, null, null);
			List<PatientMovementRestriction> pmrList = new ArrayList<PatientMovementRestriction>();
			while (cMov.moveToNext()) {
				PatientMovementRestriction pmr = new PatientMovementRestriction();
				pmr.setId(cMov.getInt(0));
				pmr.setPatient(cMov.getInt(1));
				pmr.setMovementRestriction(cMov.getInt(2));
				pmr.setPatientUsedAid(cMov.getInt(3));
				pmr.setValue(cMov.getInt(4));
				pmrList.add(pmr);
			}
			pb.setPatientMovementRestriction(pmrList);
			Cursor cAid = db.query("PatientUsedAid", new String[] {
					"CentralId", "patientId", "UsedAidId" }, "patientId=?",
					new String[] { Integer.toString(cPatient.getInt(0)) },
					null, null, null);
			List<PatientUsedAid> puaList = new ArrayList<PatientUsedAid>();
			while (cAid.moveToNext()) {
				PatientUsedAid pua = new PatientUsedAid();
				pua.setId(cAid.getInt(0));
				pua.setPatient(cAid.getInt(1));
				pua.setUsedAid(cAid.getInt(2));
				puaList.add(pua);
			}
			pb.setPatientUsedAid(puaList);
			sb.setPatientbundle(pb);

			sbList.put(screeningId, sb);
		}
		
		return sbList;
	}

	public void processRespond(PatientBundle patientBundle) {
		
		// patient data
		Patient patient = patientBundle.getPatient();
		
		db.delete("PatientDetail", "PatientId=?", new String[] { Integer.toString(patient.getId()) });
		db.delete("PatientUsedAid", "PatientId=?", new String[] { Integer.toString(patient.getId()) });
		db.delete("PatientMovementRestriction", "PatientId=?", new String[] { Integer.toString(patient.getId()) });
		db.delete("BuildingDetail", "BuildingId=?", new String[] { Integer.toString(patient.getBuilding().getId()) });
		
		ContentValues args = new ContentValues();

		args.put(KEY_ROWID, patient.getId());
		args.put("FirstName", patient.getFirstName());
		args.put("LastName", patient.getLastName());
		args.put("Gender", patient.getGender());
		args.put("DayOfBirth", patient.getDayOfBirthString());
		args.put("Weight", patient.getWeight());
		args.put("Length", patient.getLength());
		args.put("BuildingId", patient.getBuilding().getId());
		args.put("MaritalStatus", patient.getMaritalStatus());
		args.put("TelNumber", patient.getTelNumber());
		args.put("Email", patient.getEmail());
		args.put("ContactFirstName", patient.getContactFirstName());
		args.put("ContactLastName", patient.getContactLastName());
		args.put("ContactRelation", patient.getContactRelation());
		args.put("contactTelNumber", patient.getContactTelNumber());
		args.put("ContactEmail", patient.getContactEmail());

		if (db.update("Patient", args, KEY_ROWID + "=" + patient.getId(), null) == 0) {
			db.insert("Patient", null, args);
		}
		
		for (PatientDetail patientDetail : patientBundle.getPatientDetail()) {
			
			args = new ContentValues();

			args.put("CentralId", patientDetail.getId());
			args.put("PatientId", patientDetail.getPatient());
			args.put("PatientSpecId", patientDetail.getPatientSpec());
			args.put("Value", patientDetail.getValue());

			if (db.update("PatientDetail", args, "CentralId" + "="
					+ patientDetail.getId(), null) == 0) {
				db.insert("PatientDetail", null, args);
			}
		}

		for (PatientUsedAid patientUsedAid : patientBundle.getPatientUsedAid()) {

			args = new ContentValues();

			args.put("CentralId", patientUsedAid.getId());
			args.put("PatientId", patientUsedAid.getPatient());
			args.put("UsedAidId", patientUsedAid.getUsedAid());

			if (db.update("PatientUsedAid", args, "CentralId" + "="
					+ patientUsedAid.getId(), null) == 0) {
				db.insert("PatientUsedAid", null, args);
			}
		}

		for (PatientMovementRestriction patientMovementRestriction : patientBundle
				.getPatientMovementRestriction()) {

			args = new ContentValues();

			args.put("CentralId", patientMovementRestriction.getId());
			args.put("PatientId", patientMovementRestriction.getPatient());
			args.put("MovementRestrictionId",
					patientMovementRestriction.getMovementRestriction());
			args.put("PatientUsedAidId",
					patientMovementRestriction.getPatientUsedAid());
			args.put("Value", patientMovementRestriction.getValue());
			if (db.update("PatientMovementRestriction", args, "CentralId" + "="
					+ patientMovementRestriction.getId(), null) == 0) {
				db.insert("PatientMovementRestriction", null, args);
			}

		}

		// building data
		Building building = patientBundle.getPatient().getBuilding();
		args = new ContentValues();

		args.put(KEY_ROWID, building.getId());
		args.put("Street", building.getStreet());
		args.put("Number", building.getNumber());
		args.put("CityId", building.getCity());
		args.put("YearOfConstruction", building.getYearOfConstructionString());
		args.put("BuildingTypeId", building.getBuildingType());

		if (db.update("Building", args, KEY_ROWID + "=" + building.getId(),
				null) == 0) {
			db.insert("Building", null, args);
		}

		for (BuildingDetail buildingDetail : patientBundle.getBuildingDetail()) {

			args = new ContentValues();

			args.put("CentralId", buildingDetail.getId());
			args.put("BuildingId", buildingDetail.getBuilding());
			args.put("BuildingSpecId", buildingDetail.getBuildingSpec());
			args.put("Value", buildingDetail.getValue());

			if (db.update("BuildingDetail", args,
					"CentralId" + "=" + building.getId(), null) == 0) {
				db.insert("BuildingDetail", null, args);
			}
		}
	}
	
	public List<byte[]> getPictures(int ItemId) {
		Cursor cPicture = db.query("PictureItem", new String[] {
				KEY_ROWID, "Path" }, "ScreeningItemId=?",
				new String[] { Integer.toString(ItemId) }, null, null,
				null);

		List<byte[]> pictures = new ArrayList<byte[]>();
		while (cPicture.moveToNext()) {
			// read the file given from the path
			try {
				File file = new File(cPicture.getString(1));
				FileInputStream in = new FileInputStream(file);
				byte[] picture = new byte[(int) file.length()];
				in.read(picture);
				pictures.add(picture);
				in.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return pictures;
	}

}
